package com.shjn.squirrel;

import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

import com.example.x6.serial.SerialPort;
import com.google.gson.Gson;
import com.shjn.squirrel.activity.BaseActivity;
import com.shjn.squirrel.application.MyApplication;
import com.shjn.squirrel.bean.httpBean.DeviceIdReq;
import com.shjn.squirrel.bean.httpBean.HandShakeReq;
import com.shjn.squirrel.bean.httpBean.OpenBoxNotificationReq;
import com.shjn.squirrel.bean.httpBean.ParamBean;
import com.shjn.squirrel.bean.httpBean.RespCommonResult;
import com.shjn.squirrel.bean.storageBean.WastePrice;
import com.shjn.squirrel.bean.storageBean.WorkSetting;
import com.shjn.squirrel.customView.BackAndTimerView;
import com.shjn.squirrel.fragment.BackgroundFragment;
import com.shjn.squirrel.fragment.BottomFragment;
import com.shjn.squirrel.fragment.InitPageFragment;
import com.shjn.squirrel.fragment.TopFragment;
import com.shjn.squirrel.model.Constant;
import com.shjn.squirrel.model.LocalStorage;
import com.shjn.squirrel.model.UserInfoCache;
import com.shjn.squirrel.utils.MqttUtil;
import com.shjn.squirrel.utils.OkhttpHelper;
import com.shjn.squirrel.utils.SerialPortUtils;
import com.shjn.squirrel.utils.SoundPlayUtils;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;

public class MainActivity extends BaseActivity{

    //倒计时
    public BackAndTimerView mBackAndTimer;
    //串口
    public SerialPortUtils serialPortUtils = new SerialPortUtils("/dev/ttyS4", 9600);
    public SerialPort serialPort;
    private String reciveData = "";
    private byte[] mBuffer;
    private Handler handler = new Handler();
    //垃圾价格更新线程
    private Thread priceThread;
    //MQTT实例
//    private MqttUtil mqttUtil = MqttUtil.getInstance(MyApplication.getInstance());

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        EventBus.getDefault().register(this);
        init();

    }
    //订阅推送消息
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(String msg) {
//        Toast.makeText(this,msg,Toast.LENGTH_SHORT).show();
    }

//    //屏幕触摸事件
//    @Override
//    public boolean dispatchTouchEvent(MotionEvent ev) {
//        switch (ev.getAction()) {
//            case MotionEvent.ACTION_DOWN:
//                //有按下发布
//                mqttUtil.publish("t1","down",0);
//                break;
//            case MotionEvent.ACTION_UP:
//                //抬起发布
//                mqttUtil.publish("t2","up",0);
//                break;
//        }
//        return super.dispatchTouchEvent(ev);
//    }

    /**
     * 初始化
     */
    private void init() {
        //初始化倒计时控件（默认隐藏）
        mBackAndTimer = (BackAndTimerView) findViewById(R.id.backAndTime);
        mBackAndTimer.setVisibleState(false);
        //初始化串口
        serialPort = serialPortUtils.openSerialPort();
        setListener();
        //定时更新垃圾价格
//        priceThread = new PriceThread();
//        priceThread.start();
        //加载初始化页
        getFragmentManager().beginTransaction()
                .replace(R.id.boot, BackgroundFragment.getInstance())
                .replace(R.id.top, TopFragment.getInstance().setRecyclerPortalState(false))
                .replace(R.id.mid, InitPageFragment.getInstance())
                .replace(R.id.bottom, BottomFragment.getInstance())
                .commit();
    }

    /**
     * 串口数据监听
     */
    private void setListener() {
        serialPortUtils.setReceiveListener(new SerialPortUtils.ReceiveListener() {
            @Override
            public void dataReceive(byte[] buffer, int size) {
                mBuffer = buffer;
                handler.post(runnable);
            }

            //开线程更新UI
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    if (mBuffer.length > 0) {
                        reciveData += new String(mBuffer).trim();
                        if (reciveData.contains("@")) {
                            Log.e("SerialPortUtils", "数据监听：" + reciveData);
                            String[] re = reciveData.split("@");
                            if (re.length >= 1 && re[0].length() > 1) {
                                getFrindData(re[0]);
                            }
                            reciveData = "";
                        }
                    }
                }
//                    } catch (UnsupportedEncodingException e)
//                    {
//                        e.printStackTrace();
//                    }

//                }
            };
        });

    }

    /**
     * 监听主板信息和数据过滤
     */
    private void getFrindData(String data) {
        //定时上报
        if (data.startsWith("S")) {
            //周期性握手
            Map<String, String> info = getInfo(data, 0);
            postHandShake(info);
        }
        //故障上报
        if(data.startsWith("W")){
            if (data.startsWith("W3:")) {
                //电机打开故障
                postPitchOpen(0);
            }
        }
        //事件上报
        if (data.startsWith("E")) {
            if (data.startsWith("E27:")) {
                //投口打开确认
                postPitchOpen(1);

            } else if (data.startsWith("E21:")) {
                //投递记录
                Map<String, String> info = getInfo(data, 0);
                postDeliver(info);
            } else if (data.startsWith("E26:")) {
                //巡检结束关门
                postCloseBox();
            }
        }
        //心跳
        if (data.startsWith("OK")) {
            Log.i("info", "serialHeart: ok");
        }
    }

    /**
     * 以键值对形式提取串口返回的数据
     *
     * @param data
     * @param flag 0: 指令键值对 1：参数键值对
     * @return
     */
    private Map<String, String> getInfo(String data, int flag) {
        Map<String, String> map = new HashMap<>();
        if (data == null || data.equals("")) {
            return map;
        }
        String[] details = data.split(flag == 0 ? ";" : ",");
        for (String line : details) {
            String[] arr = line.split(flag == 0 ? ":" : "-");
            String key = arr[0];
            String v = arr.length > 1 ? arr[1] : "";
        }
        return map;
    }

    /**
     * 上报周期性握手信息
     *
     * @param info
     */
    private void postHandShake(Map<String, String> info) {
        HandShakeReq handShakeReq = new HandShakeReq(LocalStorage.getDeviceID(MyApplication.getInstance()),
                "898600562209A0715741", LocalStorage.getLocation(MyApplication.getInstance()).getLongitude(),
                LocalStorage.getLocation(MyApplication.getInstance()).getLatitude(), null);
        ArrayList<ParamBean> paramList = new ArrayList<>();
        //提取垃圾分类桶参数
        Map<String, String> quantityMap = getInfo(info.get("S61"), 1);//桶容量
        Map<String, String> weightMap = getInfo(info.get("S62"), 1);//桶重量
        Map<String, String> fullMap = getInfo(info.get("E22"), 1);//满桶状态
        Map<String, String> overLoadMap = getInfo(info.get("E23"), 1);//超重状态
        Map<String, String> overTempMap = getInfo(info.get("E24"), 1);//超温状态
        for (int i = 0; i < 8; i++) {
            int quantity = 0;
            if (quantityMap.get(Constant.numberMap.get(i + 1).toString()) != null) {
                quantity = Integer.parseInt(quantityMap.get(Constant.numberMap.get(i + 1).toString()));
            }
            double weight = 0;
            if (weightMap.get(Constant.numberMap.get(i + 1).toString()) != null) {
                weight = Double.parseDouble(weightMap.get(Constant.numberMap.get(i + 1).toString())) * 10 / 1000;
            }

            int canFullStatus = 0;
            if (fullMap.get(Constant.numberMap.get(i + 1).toString()) != null ||
                    overLoadMap.get(Constant.numberMap.get(i + 1).toString()) != null) {
                canFullStatus = 2;//满箱
            } else if (quantity >= 80 || weight >= Constant.weightLimit * 0.8) {
                canFullStatus = 1;//80%
            }

            int temperature = 0;
            if (overTempMap.get(Constant.numberMap.get(i + 1).toString()) != null) {
                temperature = Integer.parseInt(overTempMap.get(Constant.numberMap.get(i + 1).toString()));
            }

            paramList.add(new ParamBean(i + 1, quantity, weight, canFullStatus, temperature));
        }
        handShakeReq.setParam(paramList);
        //保存分类桶状态
        LocalStorage.saveCanState(MyApplication.getInstance(), paramList);
        //通知握手信息
        EventBus.getDefault().post(paramList);
        //上传握手信息(Constant.baseUrl + "machine/setting/handshake")
        OkhttpHelper.postRequest(Constant.myBaseUrl + "squirrelWebDemo/handShakeServlet",
                new Gson().toJson(handShakeReq),
                new Callback() {
                    @Override
                    public void onFailure(Call call, IOException e) {
                        Log.i("info", "handshake_onFailure: " + e.getMessage());
                    }

                    @Override
                    public void onResponse(Call call, Response response) {
                        try {
                            RespCommonResult result = new Gson().fromJson(response.body().string(), RespCommonResult.class);
                            if (result.getStateCode() == 1) {
                                WorkSetting workSetting = LocalStorage.getWorkSetting(MyApplication.getInstance());
                                if (result.getResult().get("serviceTel") != null) {
                                    final String serviceTel = (String) result.getResult().get("serviceTel");
                                    workSetting.setServiceTel(serviceTel);
                                    //更新客服电话
                                    runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            TopFragment.getInstance().setServiceTel(serviceTel);
                                        }
                                    });
                                }
                                if (result.getResult().get("openDutyCycle") != null) {
                                    int openDutyCycle = (int) ((double) result.getResult().get("openDutyCycle"));
                                    workSetting.setOpenDutyCycle(openDutyCycle);
//                                    //分桶设置-投口电机开门占空比
                                    serialPortUtils.sendSerialPort("androidP139:"+"0-"+openDutyCycle+",1-"+openDutyCycle+",2-"+openDutyCycle
                                            + ",3-"+openDutyCycle+",4-"+openDutyCycle+",5-"+openDutyCycle+",6-"+openDutyCycle+";");
                                }
                                if (result.getResult().get("openCurrentLimit") != null) {
                                    int openCurrentLimit = (int) ((double) result.getResult().get("openCurrentLimit"));
                                    workSetting.setOpenCurrentLimit(openCurrentLimit);
//                                    //分桶设置-投口电机开门电流限值
                                    serialPortUtils.sendSerialPort("androidP140:"+"0-"+openCurrentLimit+",1-"+openCurrentLimit+",2-"+openCurrentLimit
                                            + ",3-"+openCurrentLimit+",4-"+openCurrentLimit+",5-"+openCurrentLimit+",6-"+openCurrentLimit+";");
                                }
                                if (result.getResult().get("closeDutyCycle") != null) {
                                    int closeDutyCycle = (int) ((double) result.getResult().get("closeDutyCycle"));
                                    workSetting.setCloseDutyCycle(closeDutyCycle);
//                                    //分桶设置-投口电机关门占空比
                                    serialPortUtils.sendSerialPort("androidP141:"+"0-"+closeDutyCycle+",1-"+closeDutyCycle+",2-"+closeDutyCycle
                                            + ",3-"+closeDutyCycle+",4-"+closeDutyCycle+",5-"+closeDutyCycle+",6-"+closeDutyCycle+";");
                                }
                                if (result.getResult().get("closeCurrentLimit") != null) {
                                    int closeCurrentLimit = (int) ((double) result.getResult().get("closeCurrentLimit"));
                                    workSetting.setCloseCurrentLimit(closeCurrentLimit);
//                                    //分桶设置-投口电机关门电流限值
                                    serialPortUtils.sendSerialPort("androidP142:"+"0-"+closeCurrentLimit+",1-"+closeCurrentLimit+",2-"+closeCurrentLimit
                                            + ",3-"+closeCurrentLimit+",4-"+closeCurrentLimit+",5-"+closeCurrentLimit+",6-"+closeCurrentLimit+";");
                                }
                                if (result.getResult().get("holdTime") != null) {
                                    int holdTime = (int) ((double) result.getResult().get("holdTime"));
                                    workSetting.setHoldTime(holdTime);
//                                    //分桶设置-投口开门保持时间
                                    serialPortUtils.sendSerialPort("androidP143:"+"0-"+holdTime+",1-"+holdTime+",2-"+holdTime
                                            + ",3-"+holdTime+",4-"+holdTime+",5-"+holdTime+",6-"+holdTime+";");
                                }
                                if (result.getResult().get("handshakeCycle") != null) {
                                    int handshakeCycle = (int) ((double) result.getResult().get("handshakeCycle"));
                                    workSetting.setHandshakeCycle(handshakeCycle);
//                                    //系统数值设置-握手周期
                                    serialPortUtils.sendSerialPort("androidP201:"+handshakeCycle+";");
                                }
                                if (result.getResult().get("detectionCycle") != null) {
                                    int detectionCycle = (int) ((double) result.getResult().get("detectionCycle"));
                                    workSetting.setDetectionCycle(detectionCycle);
//                                    //系统数值设置-检测周期
                                    serialPortUtils.sendSerialPort("androidP206:"+detectionCycle+";");
                                }
                                if (result.getResult().get("rightWeightClear") != null) {
                                    int rightWeightClear = (int) ((double) result.getResult().get("rightWeightClear"));
                                    workSetting.setRightWeightClear(rightWeightClear);
//                                    //所有称重板1清零
//                                    serialPortUtils.sendSerialPort("androidP601:"+rightWeightClear+";");
                                }
                                if (result.getResult().get("rightWeightAdjust") != null) {
                                    int rightWeightAdjust = (int) ((double) result.getResult().get("rightWeightAdjust"));
                                    workSetting.setRightWeightAdjust(rightWeightAdjust);
//                                    //所有称重板1校准
//                                    serialPortUtils.sendSerialPort("androidP602:"+rightWeightAdjust+";");
                                }
                                if (result.getResult().get("leftWeightClear") != null) {
                                    int leftWeightClear = (int) ((double) result.getResult().get("leftWeightClear"));
                                    workSetting.setLeftWeightClear(leftWeightClear);
//                                    //所有称重板2清零
//                                    serialPortUtils.sendSerialPort("androidP611:"+leftWeightClear+";");
                                }
                                if (result.getResult().get("leftWeightAdjust") != null) {
                                    int leftWeightAdjust = (int) ((double) result.getResult().get("leftWeightAdjust"));
                                    workSetting.setLeftWeightAdjust(leftWeightAdjust);
//                                    //所有称重板2校准
//                                    serialPortUtils.sendSerialPort("androidP612:"+leftWeightAdjust+";");
                                }
                                //保存工作状态
                                LocalStorage.saveWorkSetting(MyApplication.getInstance(), workSetting);

                            }
                        } catch (IOException e) {
                            Log.i("info", "handshake_onFailure: " + e.getMessage());
                        }
                    }
                });

    }

    /**
     * 上报投口打开状态（测试private-->public）
     * @param state
     */
    public void postPitchOpen(int state) {
        //通知投口打开
        if(state == 1){
            EventBus.getDefault().post("pitchOpen");
        }
        //投口打开状态上传到服务器
        OkhttpHelper.postRequest(Constant.baseUrl + "machine/delivery/openBoxNotify",
                new Gson().toJson(new OpenBoxNotificationReq(LocalStorage.getDeviceID(MyApplication.getInstance()), UserInfoCache.telNum, state)),
                new Callback() {
                    @Override
                    public void onFailure(Call call, IOException e) {
                        Log.i("info", "openBoxNotify_onFailure: " + e.getMessage());
                        OkhttpHelper.requestAgain(call, this);
                    }

                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        Log.i("info", "openBoxNotify_response:" + response.body().string());
                    }
                });
    }

    /**
     * 上报投递垃圾量
     *
     * @param info
     */
    private void postDeliver(Map<String, String> info) {
        Map<String, String> deliverQuantityMap = getInfo(info.get("E21"), 1);
        for (String k : deliverQuantityMap.keySet()) {
            //通知垃圾投递量
            EventBus.getDefault().post(deliverQuantityMap.get(k));
        }
    }

    /**
     * 上报巡检结束关门
     */
    private void postCloseBox() {
        //语音提示
        SoundPlayUtils.play(18);
    }

    /**
     * 更新垃圾价格线程类
     */
    private class PriceThread extends Thread {
        @Override
        public void run() {
            try {
                Thread.sleep(Constant.priceUpdateCycle * 60 * 1000);//每隔一段时间更新一次垃圾价格
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //出厂设置后，才能获取垃圾价格
            if (!LocalStorage.getDeviceID(MyApplication.getInstance()).isEmpty()) {
                OkhttpHelper.postRequest(Constant.baseUrl + "machine/home/price",
                        new Gson().toJson(new DeviceIdReq(LocalStorage.getDeviceID(MyApplication.getInstance()))),
                        new Callback() {
                            @Override
                            public void onFailure(Call call, IOException e) {
                                Log.i("info", "price_onFailure: " + e.getMessage());
                                OkhttpHelper.requestAgain(call, this);
                            }

                            @Override
                            public void onResponse(Call call, Response response) {
                                try {
                                    RespCommonResult result = new Gson().fromJson(response.body().string(), RespCommonResult.class);
                                    if (result.getStateCode() == 1) {
                                        //保存当前垃圾价格
                                        LocalStorage.saveWastePrice(MyApplication.getInstance(), (ArrayList<WastePrice>) result.getResult().get("wastePrice"));
                                    }
                                } catch (IOException e) {
                                    Log.i("info", "price_onFailure: " + e.getMessage());
                                    OkhttpHelper.requestAgain(call, this);
                                }
                            }
                        });
            }

        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i("info", "MainActivity: onDestroy");
        //关闭串口
        if (serialPortUtils != null) {
            serialPortUtils.closeSerialPort();
        }
        //关闭垃圾价格更新线程
        if (priceThread != null) {
            priceThread.interrupt();
        }
        EventBus.getDefault().unregister(this);
    }

}